package zero.tech.redis.queue;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.Pipeline;
import zero.tech.redis.config.RedisQueueConfig;
import zero.tech.redis.config.RedisQueueConfig.QueueMode;

@Component
public class QueueUtil {
	@Autowired(required = false)
	private JedisCluster jedisQueueCluster;
	@Autowired(required = false)
	private JedisSentinelPool jedisSentinelQueuePool;
	@Autowired(required = false)
	private JedisPool jedisQueuePool;
	@Autowired(required = false)
	private RedisQueueConfig config;
	
	public void putQueue(String queue, Object... objs) {
		if(objs.length>0) {
			String[] msgs=new String[objs.length];
			int index=0;
			for(Object obj:objs) {
				msgs[index++]=JSONObject.toJSONString(obj);
			}
			putQueue(queue, msgs);
		}
	}

	public void putQueue(String queue, String... msgs) {
		if(QueueMode.STANDALONE.equals(config.getMode())) {
			Jedis jedis = null;
			try {
				jedis = jedisQueuePool.getResource();
				jedis.lpush(queue, msgs);
			} finally {
				if (jedis != null) {
					jedis.close();
				}
			}
		}else if(QueueMode.SENTINEL.equals(config.getMode())) {
			Jedis jedis = null;
			try {
				jedis = jedisSentinelQueuePool.getResource();
				jedis.lpush(queue, msgs);
			} finally {
				if (jedis != null) {
					jedis.close();
				}
			}
		}else if(QueueMode.CLUSTER.equals(config.getMode())) {
			jedisQueueCluster.lpush(queue, msgs);
		}else {
			throw new RuntimeException("找不到redis mode:"+config.getMode());
		}
	}
	


	public String pullQueue(String queue) {
		String msg = null;
		if(QueueMode.STANDALONE.equals(config.getMode())) {
			Jedis jedis = null;
			try {
				jedis = jedisQueuePool.getResource();
				msg = jedis.rpop(queue);
			} finally {
				if (jedis != null) {
					jedis.close();
				}
			}
		}else if(QueueMode.SENTINEL.equals(config.getMode())) {
			Jedis jedis = null;
			try {
				jedis = jedisSentinelQueuePool.getResource();
				msg = jedis.rpop(queue);
			} finally {
				if (jedis != null) {
					jedis.close();
				}
			}
		}else if(QueueMode.CLUSTER.equals(config.getMode())) {
			msg=jedisQueueCluster.rpop(queue);
		}else {
			throw new RuntimeException("找不到redis mode:"+config.getMode());
		}
		return msg;
	}

	public List<String> pullQueueBatch(String queue, int size) {
		List<String> strs = new ArrayList<String>();
		if(QueueMode.STANDALONE.equals(config.getMode())) {
			Jedis jedis = null;
			try {
				jedis = jedisQueuePool.getResource();
				Pipeline pipeline = jedis.pipelined();
				for (int i = 0; i < size; i++) {
					pipeline.rpop(queue);
				}
				List<Object> list = pipeline.syncAndReturnAll();
				for (Object obj : list) {
					if (obj != null) {
						strs.add(obj.toString());
					}
				}
			} finally {
				if (jedis != null) {
					jedis.close();
				}
			}
		}else if(QueueMode.SENTINEL.equals(config.getMode())) {
			Jedis jedis = null;
			try {
				jedis = jedisSentinelQueuePool.getResource();
				Pipeline pipeline = jedis.pipelined();
				for (int i = 0; i < size; i++) {
					pipeline.rpop(queue);
				}
				List<Object> list = pipeline.syncAndReturnAll();
				for (Object obj : list) {
					if (obj != null) {
						strs.add(obj.toString());
					}
				}
			} finally {
				if (jedis != null) {
					jedis.close();
				}
			}
		}else if(QueueMode.CLUSTER.equals(config.getMode())) {
			for(int i=0;i<size;i++) {
				String val=jedisQueueCluster.rpop(queue);
				strs.add(val);
			}
		}else {
			throw new RuntimeException("找不到redis mode:"+config.getMode());
		}
		return strs;
	}


	public void putQueueBatch(String queue, List<? extends Object> list) {
		if(list.isEmpty()) {
			return;
		}
		String[] arrs=new String[list.size()];
		int i=0;
		for(Object obj:list) {
			arrs[i++]=JSONObject.toJSONString(obj);
		}
		putQueue(queue, arrs);
	}
	
}
